#include <rclcpp/rclcpp.hpp>
#include "performance_test_base.h"

namespace trace_api = opentelemetry::trace;
namespace nostd = opentelemetry::nostd;

class HighFrequencyTestNode : public rclcpp::Node {
public:
    HighFrequencyTestNode() : Node("high_frequency_test_node") {
        // Initialize OpenTelemetry
        PerformanceTestBase::InitTracer();
        tracer_ = trace_api::Provider::GetTracerProvider()->GetTracer("high-frequency-test");
        
        RCLCPP_INFO(this->get_logger(), "High Frequency Span Test started");
        RCLCPP_INFO(this->get_logger(), "Testing high frequency span creation performance...");
        
        runHighFrequencySpanTest();
        
        RCLCPP_INFO(this->get_logger(), "High frequency span test completed!");
    }

private:
    void runHighFrequencySpanTest() {
        RCLCPP_INFO(this->get_logger(), "Running high frequency span test...");
        
        PerformanceStats stats;
        stats.reset();
        
        stats.memory_before_kb = PerformanceTestBase::getCurrentMemoryKB();
        auto cpu_before = PerformanceTestBase::getCurrentCPUTime();
        stats.cpu_time_user_before = cpu_before.first;
        stats.cpu_time_system_before = cpu_before.second;
        
        const size_t iterations = 50000;
        
        for (size_t i = 0; i < iterations; ++i) {
            auto span_start = std::chrono::high_resolution_clock::now();
            
            auto span = tracer_->StartSpan("high_freq_span", {
                {"iteration", static_cast<int64_t>(i)},
                {"timestamp", std::chrono::duration_cast<std::chrono::milliseconds>(
                    std::chrono::system_clock::now().time_since_epoch()).count()}
            });
            
            span->End();
            
            auto span_end = std::chrono::high_resolution_clock::now();
            auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(span_end - span_start);
            
            stats.total_time += duration;
            stats.min_time = std::min(stats.min_time, duration);
            stats.max_time = std::max(stats.max_time, duration);
            stats.operation_count++;
        }
        
        stats.memory_after_kb = PerformanceTestBase::getCurrentMemoryKB();
        auto cpu_after = PerformanceTestBase::getCurrentCPUTime();
        stats.cpu_time_user_after = cpu_after.first;
        stats.cpu_time_system_after = cpu_after.second;
        
        stats.calculateAverages();
        PerformanceTestBase::printStats("High Frequency Span Creation", stats);
    }

    nostd::shared_ptr<trace_api::Tracer> tracer_;
};

int main(int argc, char* argv[]) {
    rclcpp::init(argc, argv);
    
    auto node = std::make_shared<HighFrequencyTestNode>();
    
    RCLCPP_INFO(node->get_logger(), "Starting High Frequency Span Performance Test...");
    RCLCPP_INFO(node->get_logger(), "This will test OpenTelemetry's high frequency span creation performance");
    
    rclcpp::spin(node);
    rclcpp::shutdown();
    
    return 0;
}
